package com.ly.heart.service.impl;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ly.common.core.domain.AjaxResult;
import com.ly.common.core.domain.entity.SysDept;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.StringUtils;
import com.ly.common.utils.erp.ConstUtil;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.heart.domain.MaterialDetailEntity;
import com.ly.heart.domain.WarehouseRegionEntity;
import com.ly.heart.domain.dto.StartProcessDto;
import com.ly.heart.service.IActModelService;
import com.ly.heart.service.IMaterialDetailService;
import com.ly.heart.util.ChineseToPinyin;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.system.service.ISysDeptService;
import org.springframework.stereotype.Service;
import com.ly.heart.mapper.SaleQuotationMapper;
import com.ly.heart.domain.SaleQuotationEntity;

import javax.annotation.Resource;

import com.ly.heart.service.ISaleQuotationService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 销售报价单Service业务层处理
 *
 * @author wutao
 * @date 2024-06-27
 */
@Service
public class SaleQuotationServiceImpl extends ServiceImpl<SaleQuotationMapper, SaleQuotationEntity> implements ISaleQuotationService {

    @Resource
    private SaleQuotationMapper saleQuotationMapper;
    @Resource
    private IMaterialDetailService materialDetailService;
    @Resource
    private IActModelService actModelService;
    @Resource
    private ISysDeptService sysDeptService;

    /**
     * 查询销售报价单
     *
     * @param id 销售报价单ID
     * @return 销售报价单
     */
    @Override
    public AjaxResult selectSaleQuotationById(String id) {
        SaleQuotationEntity quotationEntity = this.getById(id);
        List<MaterialDetailEntity> detailEntityList = materialDetailService.list(new LambdaQueryWrapper<>(MaterialDetailEntity.class)
                .eq(MaterialDetailEntity::getRelationId, id)
                .eq(MaterialDetailEntity::getType, ConstUtil.SALE_QUOTATION_MATERIAL_TYPE)
        );

        quotationEntity.setMaterialDetailEntities(detailEntityList);
        return AjaxResult.success(quotationEntity);
    }

    /**
     * 查询销售报价单列表
     *
     * @param saleQuotation 销售报价单
     * @return 销售报价单
     */
    @Override
    public List<SaleQuotationEntity> selectSaleQuotationList(SaleQuotationEntity saleQuotation) {
        return saleQuotationMapper.selectSaleQuotationList(saleQuotation);
    }

    /**
     * 新增销售报价单
     *
     * @param saleQuotation 销售报价单
     * @return 结果
     */
    /*@Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult insertSaleQuotation(SaleQuotationEntity saleQuotation)
    {
        Date nowDate = DateUtils.getNowDate();
        String id = SnowflakeIdWorker.getInstance().nextStringId();
        saleQuotation.setId(id);
        saleQuotation.setCreateTime(nowDate);
        saleQuotation.setDeptId(CurrentUserUtil.getCompanyId());
        if (StringUtils.isEmpty(saleQuotation.getSaleQuotationCode())) {
            String companyId = CurrentUserUtil.getCompanyId();
            SysDept sysDept = sysDeptService.getById(companyId);
            int count = this.count();
            String countStr = String.format("%06d", count);
            String firstLetter = ChineseToPinyin.getFirstLetter(sysDept.getDeptName());
            String orderNumber = firstLetter.concat("_XSBJD_").concat(countStr);
            saleQuotation.setSaleQuotationCode(orderNumber);
        }

        StartProcessDto startDto = new StartProcessDto().setBusinessId(saleQuotation.getId()).setBusinessType(saleQuotation.getBusinessType()).setModelId(saleQuotation.getModelId())
                .setBusinessName("销售报价单_".concat(saleQuotation.getId()));
        String instanceId = actModelService.startProcess(startDto);
        saleQuotation.setInstanceId(instanceId);
        this.materialDetailEntities(saleQuotation.getMaterialDetailEntities(),id,nowDate);
        boolean save = this.save(saleQuotation);
        if (!save){
            return AjaxResult.error("新增报价单失败");
        }else{
            return AjaxResult.success("新增报价单成功");
        }
    }*/
    @Override
    public AjaxResult draft(SaleQuotationEntity saleQuotation) {
        boolean saved;
        if (StringUtils.isEmpty(saleQuotation.getId())){
            Date nowDate = DateUtils.getNowDate();
            String id = SnowflakeIdWorker.getInstance().nextStringId();
            saleQuotation.setId(id);
            saleQuotation.setCreateTime(nowDate);
            saleQuotation.setDeptId(CurrentUserUtil.getCompanyId());
            if (StringUtils.isEmpty(saleQuotation.getSaleQuotationCode())) {
                String companyId = CurrentUserUtil.getCompanyId();
                SysDept sysDept = sysDeptService.getById(companyId);
                int count = this.count();
                String countStr = String.format("%06d", count);
                String firstLetter = ChineseToPinyin.getFirstLetter(sysDept.getDeptName());
                String orderNumber = firstLetter.concat("_XSBJD_").concat(countStr);
                saleQuotation.setSaleQuotationCode(orderNumber);
            }
            saleQuotation.setState(ConstUtil.STATE_IN_DRAFT);
            saved = this.save(saleQuotation);
            this.materialDetailEntities(saleQuotation.getMaterialDetailEntities(), saleQuotation.getId(), saleQuotation.getCreateTime(), "draft");
        }else{
            this.materialDetailEntities(saleQuotation.getMaterialDetailEntities(), saleQuotation.getId(), saleQuotation.getCreateTime(), "submit");
            saved = this.updateById(saleQuotation);
        }
        if (!saved) {
            return AjaxResult.error("暂存报价单失败");
        } else {
            return AjaxResult.success("暂存报价单成功",saleQuotation.getId());
        }
    }

    @Override
    public AjaxResult submit(SaleQuotationEntity saleQuotation) {
        if (StringUtils.isEmpty(saleQuotation.getId())) {
            return AjaxResult.error("请先暂存该单据！");
        }
        Date nowDate = DateUtils.getNowDate();
        StartProcessDto startDto = new StartProcessDto().setBusinessId(saleQuotation.getId()).setBusinessType(saleQuotation.getBusinessType()).setModelId(saleQuotation.getModelId())
                .setBusinessName("销售报价单_".concat(saleQuotation.getId()));
        String instanceId = actModelService.startProcess(startDto);
        saleQuotation.setInstanceId(instanceId);
        this.materialDetailEntities(saleQuotation.getMaterialDetailEntities(), saleQuotation.getId(), nowDate, "submit");
        saleQuotation.setState(ConstUtil.STATE_IN_PROCESS);
        if (this.updateById(saleQuotation)) {
            return AjaxResult.success("提交报价单成功");
        } else {
            return AjaxResult.error("提交报价单失败");
        }
    }


    private void materialDetailEntities(List<MaterialDetailEntity> materialDetailEntities, String saleQuotationId, Date nowDate, String type) {
        if (!CollectionUtils.isEmpty(materialDetailEntities)) {
            if ("submit".equals(type)) {
                boolean remove = materialDetailService.remove(new LambdaQueryWrapper<MaterialDetailEntity>().eq(MaterialDetailEntity::getRelationId, saleQuotationId)
                        .eq(MaterialDetailEntity::getType, ConstUtil.SALE_QUOTATION_MATERIAL_TYPE)
                );
                if (!remove) {
                    new RuntimeException("删除报价单物料明细失败");
                }
            }
            materialDetailEntities.forEach(materialDetailEntity -> {
                materialDetailEntity.setId(SnowflakeIdWorker.getInstance().nextStringId());
                materialDetailEntity.setRelationId(saleQuotationId);
                materialDetailEntity.setCreateTime(nowDate);
                materialDetailEntity.setType(ConstUtil.SALE_QUOTATION_MATERIAL_TYPE);
            });
            boolean b = materialDetailService.saveBatch(materialDetailEntities);
            if (!b) {
                new RuntimeException("新增报价单物料明细失败");
            }
        }
    }

    /**
     * 修改销售报价单
     *
     * @param saleQuotation 销售报价单
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateSaleQuotation(SaleQuotationEntity saleQuotation) {
        if (ConstUtil.IS_QUOTE_YES.equals(saleQuotation.getIsQuote())){
            return AjaxResult.error("该报价单已使用，不能修改");
        }
        if (!ConstUtil.STATE_IN_DRAFT.equals(saleQuotation.getState())){
            return AjaxResult.error("只允修改暂存状态的报价单");
        }
        saleQuotation.setUpdateTime(DateUtils.getNowDate());
        boolean updated = this.updateById(saleQuotation);
        if (!updated) {
            return AjaxResult.error("修改销售报价单失败");
        }
        if (!CollectionUtils.isEmpty(saleQuotation.getMaterialDetailEntities())) {
            List<MaterialDetailEntity> detailEntityList = materialDetailService.list(new LambdaQueryWrapper<>(MaterialDetailEntity.class)
                    .eq(MaterialDetailEntity::getRelationId, saleQuotation.getId())
                    .eq(MaterialDetailEntity::getType, ConstUtil.SALE_QUOTATION_MATERIAL_TYPE)
            );
            Set<String> existingIds = detailEntityList.stream()
                    .filter(w -> StringUtils.isNotEmpty(w.getId()))
                    .map(detail -> detail.getId()).collect(Collectors.toSet());
            List<MaterialDetailEntity> toBeDeleted = detailEntityList.stream()
                    .filter(entity -> !existingIds.contains(entity.getId()))
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(toBeDeleted)) {
                List<String> removeIds = toBeDeleted.stream().map(MaterialDetailEntity::getId).collect(Collectors.toList());
                boolean removed = materialDetailService.removeByIds(removeIds);
                if (!removed) {
                    return AjaxResult.error("更新报价单明细失败");
                }
            }
            for (MaterialDetailEntity materialDetailEntity : saleQuotation.getMaterialDetailEntities()) {
                if (StringUtils.isEmpty(materialDetailEntity.getId())) {
                    materialDetailEntity.setId(SnowflakeIdWorker.getInstance().nextStringId());
                    materialDetailEntity.setRelationId(saleQuotation.getId());
                    materialDetailEntity.setType(ConstUtil.SALE_QUOTATION_MATERIAL_TYPE);
                    materialDetailEntity.setCreateTime(DateUtils.getNowDate());
                    materialDetailService.save(materialDetailEntity);
                } else {
                    materialDetailService.updateById(materialDetailEntity);
                }
            }
        }
        return AjaxResult.success();
    }

    /**
     * 批量删除销售报价单
     *
     * @param ids 需要删除的销售报价单ID
     * @return 结果
     */
    @Override
    public AjaxResult deleteSaleQuotationByIds(String[] ids) {
        boolean removed = this.removeByIds(Arrays.asList(ids));
        if (!removed) {
            return AjaxResult.error("删除销售报价单失败");
        }
        boolean remove = materialDetailService.remove(new LambdaQueryWrapper<MaterialDetailEntity>().in(MaterialDetailEntity::getRelationId, ids)
                .eq(MaterialDetailEntity::getType, ConstUtil.SALE_QUOTATION_MATERIAL_TYPE));
        if (!remove) {
            return AjaxResult.error("删除销售报价单物料明细失败");
        }
        return AjaxResult.success();
    }

    /**
     * 删除销售报价单信息
     *
     * @param id 销售报价单ID
     * @return 结果
     */
    @Override
    public int deleteSaleQuotationById(String id) {
        return saleQuotationMapper.deleteSaleQuotationById(id);
    }
}
